package com.shopping_assistant.view;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.shopping_assistant.model.ShoppingInterpreter;
import com.shopping_assistant.model.Shop;
import com.shopping_assistant.model.ShopController;
import com.shopping_assistant.view.overlays.SAItemizedOverlay;
import com.shopping_assistant.view.overlays.SAOverlayItem;

public class GoogleMapView extends MapActivity {
	
	// Constants
	private static final Boolean Running_Emulator = false;
	private static final Boolean AreZoomControlsEnabled = true;
	private static final double MAPSCALE = 1E6;
	
	private SALocationOverlay myLocationOverlay;
	private MapView map;
	private MapController mapController;
	private SAItemizedOverlay saItemizedOverlay;
	private List<Overlay> mapOverlays;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.google_map_view);
        
        setupView();
    }
	
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    
    // adding mylocationoverlay
    private void setupView() {
    	
    	map = (MapView) findViewById(R.id.google_map_view);
		mapController = map.getController();
		mapOverlays = map.getOverlays();
    	
 		myLocationOverlay = new SALocationOverlay(this, map);
 		map.getOverlays().add(myLocationOverlay);
 		myLocationOverlay.enableMyLocation();
 		map.setBuiltInZoomControls(AreZoomControlsEnabled);
 		
 		myLocationOverlay.runOnFirstFix(new Runnable() {
 			
 			public void run() {

 				map.post(new Runnable() {
 					
 					public void run() {
 						
 						if(myLocationOverlay.getMyLocation() != null)
 							moveMapPosition(myLocationOverlay.getMyLocation());
 					}
 				});
 			}
 		});
 		
 		addShops(null);
 		ShoppingInterpreter inter = new ShoppingInterpreter(saItemizedOverlay);
 		myLocationOverlay.addLocationListener(inter);
 		
 		if(Running_Emulator) {
 			TestProvider provider = new TestProvider(this);
 			provider.start();
 		}
    }
    
	private void moveMapPosition(GeoPoint center, int latSpan, int longSpan) {

		if (center != null) {
			mapController.stopAnimation(false);
			mapController.animateTo(center);

			if (latSpan != -1 && longSpan != -1)
				mapController.zoomToSpan((int) (latSpan * 1E1), (int) (longSpan * 1E1));

		}
	}
	
	private void moveMapPosition(GeoPoint center) {
		moveMapPosition(center, (int) ShopController.LATITUDE_PER_KM / 4, (int) ShopController.LONGTITUDE_PER_KM / 4);
	}
	
	/**
	 * This function adds the AEDs within the map showed to the overlay.
	 * 
	 * @param location
	 *            The center of the map.
	 */
	private void addShops(GeoPoint plocation) {

//		GeoPoint location = null;
//
//		if (plocation != null)
//			location = plocation;
//		else {
//			location = map.getMapCenter();
//			Log.d("ViewMapActivity.addAED",
//					"Called with null Location. Mapcenter is used");
//		}
//
//		Log.d("SHOP", "ViewMapActivity.addAED starting");
//		// Finds the screen center and the spanning box containing the
//		// entire mapview.
//		double deltaX = map.getLatitudeSpan();
//		double deltaY = map.getLongitudeSpan();
//
//		double rightX = (location.getLatitudeE6() + (deltaX / 2)) / MAPSCALE;
//		double topY = (location.getLongitudeE6() + (deltaY / 2)) / MAPSCALE;
//
//		double leftX = (location.getLatitudeE6() - (deltaX / 2)) / MAPSCALE;
//		double bottomY = (location.getLongitudeE6() - (deltaY / 2)) / MAPSCALE;
//
//		Log.d("SHOP event", String.format(
//				"leftX: %s, rightX: %s, bottomY: %s, bottomY: %s", leftX,
//				rightX, bottomY, topY));

		// Finding the relevant AED's
		Log.d("AED", "ViewMapActivity.addAED finding relevant AED's");
		List<Shop> shopList = ShopController.getInstance().getShops();
		List<GeoPoint> shopGeoList = new ArrayList<GeoPoint>();

		Log.d("AED event", "list size: " + shopList.size());

		for (Shop shop : shopList) {
			int geoLat = (int) (shop.getLatitude() * 1E6);
			int geoLong = (int) (shop.getLongitude() * 1E6);

			shopGeoList.add(new GeoPoint(geoLat, geoLong));
		}

		// setting up aedLocationOverlay if first use
		Log.d("AED", "ViewMapActivity.addAED prepping aedLocationOverlay");
		if (saItemizedOverlay == null) {
			Drawable aedIcon = this.getResources().getDrawable(
					R.drawable.icon18);
			saItemizedOverlay = new SAItemizedOverlay(aedIcon, this,
					myLocationOverlay);
			mapOverlays.add(saItemizedOverlay);
		}

		GeoPoint gp = null;
		Shop shop = null;
		// clearing the aed overlay and adds the relevant aed's
		Log.d("AED", "ViewMapActivity.addAED clearing overlay and adding new AED's");
		saItemizedOverlay.clearOverlay();

		for (int i = 0; i < shopList.size(); i++) {
			gp = shopGeoList.get(i);
			shop = shopList.get(i);

			Log.d("AED geo", gp.toString());
			saItemizedOverlay.addOverlay(new SAOverlayItem(gp, "SAGeoPoint",
					gp.toString(), shop));
		}

		// forces the map to redraw
		map.postInvalidate();
		Log.d("AED", "ViewMapActivity.addAED done!");

	}
	
	/**
	 * This class handles the touch events from the MapView and facilitates
	 * updates when panning and zooming.
	 * 
	 * @author LH
	 */
	private class TouchListener implements OnTouchListener {

		private Timer timer;
		private TimerTask task;

		public boolean onTouch(View v, MotionEvent event) {

			if (timer != null && task != null) {
				task.cancel();
				timer.cancel();
			}

			startTimer();

			return false;
		}

		private void startTimer() {
			timer = new Timer();
			task = new TouchTask();

			timer.schedule(task, 1000);
		}

		private class TouchTask extends TimerTask {

			public void run() {

				map.post(new Runnable() {

					public void run() {
						// addAED(map.getMapCenter());

						Log.d("AED event", "addAED called");
					}
				});
			}
		}
	}
}